package org.cainiao.basic.inherit.test2;

/**
 * <br />
 * <p>
 * Author: Cai Niao(wdhlzd@163.com)<br />
 */
public class Child extends Parent {

    public String name = "child";

    public void c() {
        /*
         * 0: aload_0
         * 1: invokespecial #15                 // Method org/cainiao/basic/inherit/test2/Parent.p:()V
         * 这里 aload_0，将 this 放入操作数栈
         * 通过 invokespecial 调用父类的方法
         * 在父类中，this 获取到的是父类的字段
         *
         * 我的理解：
         * 从字节码指令来看
         * 无论是在 Child 方法中的 this
         * 还是在 Child 中通过 super 调用 Parent，Parent 方法中的 this
         * 都是同一个对象的指针，并不存在子对象、父对象
         * 堆内存中只有一个对象的地址，只是在这个对象上关联了子类父类而已
         * 之所以在同一个对象指针调用 getfield 指令得到的值不同
         * 是因为 Child.c() 与 Parent.p() 方法中的 getfield 指令的操作数指向的符号引用不同
         * 但是要注意，虽然实例变量由符号引用来区分，但仍然需要运行时动态链接
         * 因为符号引用区分的不是 Child 与 Parent 类位于方法区的成员地址
         * 而是由类型 Child 与 Parent 映射到堆中对象中的地址
         * 同一个字段，在不同的对象中，处于不同的位置
         * 因此 putfield 与 getfield 指令的操作数要在运行时才能由符号引用换成内存地址
         *
         * 另外，实例方法可以重写，而实例字段不能重写
         * 在父类中通过 this 访问方法时，可能通过动态链接访问到子类重写的方法
         * 但在父类中通过 this 访问成员变量时，访问的是父类的字段，不会访问到子类的同名字段
         */
        super.p();
    }
}
